package com.ycxy.school.express.service.impl;

import com.ycxy.school.express.ex.ServiceException;
import com.ycxy.school.express.mapper.OrderMapper;
import com.ycxy.school.express.mapper.PaymentMapper;
import com.ycxy.school.express.pojo.dto.OrderAddNewDTO;
import com.ycxy.school.express.pojo.dto.OrderUpdateDTO;
import com.ycxy.school.express.pojo.dto.PaymentAddNewDTO;
import com.ycxy.school.express.pojo.entity.Order;
import com.ycxy.school.express.pojo.entity.Payment;
import com.ycxy.school.express.pojo.vo.OrderDetailVO;
import com.ycxy.school.express.pojo.vo.OrderListItemVO;
import com.ycxy.school.express.security.LoginPrincipal;
import com.ycxy.school.express.service.IOrderService;
import com.ycxy.school.express.util.OrderSnUtils;
import com.ycxy.school.express.web.ServiceCode;
import com.ycxy.school.express.web.enums.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.parameters.P;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @Author jayLuo
 * @Date 2023/1/8 16:14
 * @PackageName:com.ycxy.school.express.service.impl
 * @ClassName: OrderServiceImpl
 * @Description: TODO
 * @Version 1.0
 */
@Slf4j
@Service
public class OrderServiceImpl implements IOrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private PaymentMapper paymentMapper;

    @Transactional
    @Override
    public void createOrder(OrderAddNewDTO orderAddNewDTO) {
        log.debug("开始处理【用户下订单】的业务，参数：{}", orderAddNewDTO);
        //创建Order对象
        Order order = new Order();
        LocalDateTime now = LocalDateTime.now();
        String orderSn = OrderSnUtils.getSn();
        //同名属性赋值
        BeanUtils.copyProperties(orderAddNewDTO,order);
        order.setSn(orderSn);
        order.setUserId(getUserId());
        order.setStatus(OrderStatusEnum.WAIT_DIST.getStatus());
        order.setCreateTime(now);
        order.setCreateData(now);
        //调用OrderMapper的insert方法
        int rows = orderMapper.insert(order);
        // 判断插入数据的结果是否符合预期
        if (rows != 1) {
            String message = "添加订单失败，服务器忙，请稍后再次尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_INSERT, message);
        }

        //创建Payment对象
        Payment payment = new Payment();
        payment.setOrderSn(orderSn);
        payment.setStatus(PaymentStatusEnum.WAIT_BUYER_PAY.getStatus());
        payment.setCreateData(now);
        //调用PaymentMapper的insert方法
        int rows2 = paymentMapper.insert(payment);
        // 判断插入数据的结果是否符合预期
        if (rows2 != 1) {
            String message = "添加支付数据失败，服务器忙，请稍后再次尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_INSERT, message);
        }

    }

    @Transactional
    @Override
    public void receiveOrder(Long id,String sn) {
        log.debug("开始处理【骑手接订单】的业务,参数: {}",id);
        //创建Order对象
        Order order = new Order();
        LocalDateTime now = LocalDateTime.now();
        order.setId(id);
        order.setStatus(OrderStatusEnum.TRANSPORT.getStatus());
        order.setStaffId(getUserId());
        order.setModifiedData(now);
        //调用OrderMapper的updateById方法
        int rows = orderMapper.updateById(order);
        // 判断修改数据的结果是否符合预期
        if (rows != 1) {
            String message = "接单失败，服务器忙，请稍后再次尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_UPDATE, message);
        }

        //修改支付表中收款方字段数据
        //创建Payment对象
        Payment payment = new Payment();
        payment.setOrderSn(sn);
        payment.setOnlineSeller(getUserId());
        payment.setModifiedData(now);
        //调用PaymentMapper的updateBySn方法
        int rows2 = paymentMapper.updateBySn(payment);
        // 判断修改数据的结果是否符合预期
        if (rows2 != 1) {
            String message = "修改数据失败，服务器忙，请稍后再次尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_UPDATE, message);
        }
    }

    @Override
    public void deleteByUser(Long id) {
        log.debug("开始处理【用户手动删除订单】的业务,参数: {}",id);
        //创建Order对象
        Order order = new Order();
        LocalDateTime now = LocalDateTime.now();
        order.setId(id);
        order.setIsDelete(OrderDeleteEnum.MANUAL.getType());
        order.setModifiedData(now);
        //调用OrderMapper的updateById方法
        int rows = orderMapper.updateById(order);
        // 判断修改数据的结果是否符合预期
        if (rows != 1) {
            String message = "手动删除订单失败，服务器忙，请稍后再次尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_UPDATE, message);
        }
    }

    @Override
    public void deleteBySystem(Long id) {
        log.debug("开始处理【系统删除订单】的业务,参数: {}",id);
        //创建Order对象
        Order order = new Order();
        LocalDateTime now = LocalDateTime.now();
        order.setId(id);
        order.setIsDelete(OrderDeleteEnum.SYSTEM.getType());
        order.setModifiedData(now);
        //调用OrderMapper的updateById方法
        int rows = orderMapper.updateById(order);
        // 判断修改数据的结果是否符合预期
        if (rows != 1) {
            String message = "系统删除订单失败，服务器忙，请稍后再次尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_UPDATE, message);
        }
    }

    @Override
    public void withdrawOrder(Long id) {
        log.debug("开始处理【用户撤销订单】的业务,参数: {}",id);
        //创建Order对象
        Order order = new Order();
        LocalDateTime now = LocalDateTime.now();
        order.setId(id);
        order.setIsDelete(OrderDeleteEnum.CANCEL.getType());
        order.setModifiedData(now);
        //调用OrderMapper的updateById方法
        int rows = orderMapper.updateById(order);
        // 判断修改数据的结果是否符合预期
        if (rows != 1) {
            String message = "撤销订单失败，服务器忙，请稍后再次尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_UPDATE, message);
        }
    }

    @Override
    public void updateOrder(Long id, OrderUpdateDTO orderUpdateDTO) {
        log.debug("开始处理【用户修改订单】的业务,参数: {},{}",id,orderUpdateDTO);
        //创建Order对象
        Order order = new Order();
        LocalDateTime now = LocalDateTime.now();
        //同名属性赋值
        BeanUtils.copyProperties(orderUpdateDTO,order);
        order.setId(id);
        order.setModifiedData(now);
        //调用OrderMapper的updateById方法
        int rows = orderMapper.updateById(order);
        // 判断修改数据的结果是否符合预期
        if (rows != 1) {
            String message = "修改订单失败，服务器忙，请稍后再次尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_UPDATE, message);
        }
    }

    @Override
    public List<OrderListItemVO> list() {
        log.debug("开始处理【查询订单列表】的业务");
        List<OrderListItemVO> list = orderMapper.list();
        return list;
    }

    @Override
    public List<OrderListItemVO> listByUserId() {
        log.debug("开始处理【根据用户id查询订单列表】的业务");
        List<OrderListItemVO> list = orderMapper.listByUserId(getUserId());
        return list;
    }

    @Override
    public List<OrderListItemVO> listByStaffId() {
        log.debug("开始处理【根据配送员id查询订单列表】的业务");
        List<OrderListItemVO> list = orderMapper.listByStaffId(getUserId());
        return list;
    }

    @Override
    public List<OrderListItemVO> waitOrderList() {
        log.debug("开始处理【查询等待接单的订单列表】的业务");
        Integer status = OrderStatusEnum.WAIT_DIST.getStatus();
        List<OrderListItemVO> list = orderMapper.listByStatus(status);
        return list;
    }

    @Override
    public List<OrderListItemVO> transportOrderList() {
        log.debug("开始处理【查询配送中的订单列表】的业务");
        Integer status = OrderStatusEnum.TRANSPORT.getStatus();
        List<OrderListItemVO> list = orderMapper.listByUserIdAndStatus(getUserId(),status);
        return list;
    }

    @Override
    public List<OrderListItemVO> transportOrderListByStaffId() {
        log.debug("开始处理【根据配送员id查询配送中的订单列表】的业务");
        Integer status = OrderStatusEnum.TRANSPORT.getStatus();
        List<OrderListItemVO> list = orderMapper.listByStaffIdAndStatus(getUserId(),status);
        return list;
    }

    @Override
    public List<OrderListItemVO> completeOrderListByStaffId() {
        log.debug("开始处理【根据配送员id查询订单完成的订单列表】的业务");
        Integer status = OrderStatusEnum.COMPLETE.getStatus();
        List<OrderListItemVO> list = orderMapper.listByStaffIdAndStatus(getUserId(),status);
        return list;
    }

    @Override
    public List<OrderListItemVO> listByEvaluate() {
        log.debug("开始处理【查询评论已开启的订单列表】的业务");
        Integer isEvaluate = OrderEvaluateEnum.open.getValue();
        List<OrderListItemVO> list = orderMapper.listByEvaluate(isEvaluate,getUserId());
        return list;
    }

    @Override
    public List<OrderListItemVO> listByPayTime() {
        log.debug("开始处理【查询未支付的订单列表】的业务");
        List<OrderListItemVO> list = orderMapper.listByPayTime(getUserId());
        return list;
    }

    @Override
    public List<OrderListItemVO> listByDelete() {
        log.debug("开始处理【查询已删除的订单列表】的业务");
        List<OrderListItemVO> list = orderMapper.listByIsDelete();
        return list;
    }

    @Override
    public OrderDetailVO getOrderDetail(Long id) {
        log.debug("开始处理【根据id查询订单详情】的业务,参数: {}",id);
        OrderDetailVO orderDetail = orderMapper.getOrderDetailById(id);
        return orderDetail;
    }

    @Override
    public void setComplete(Long id) {
        log.debug("开始处理【根据id修该订单状态为完成】的业务,参数: {}",id);
        //创建Order对象
        Order order = new Order();
        LocalDateTime now = LocalDateTime.now();
        order.setId(id);
        order.setStatus(OrderStatusEnum.COMPLETE.getStatus());
        order.setIsEvaluate(OrderEvaluateEnum.open.getType());
        order.setModifiedData(now);
        //调用OrderMapper的updateById方法
        int rows = orderMapper.updateById(order);
        // 判断修改数据的结果是否符合预期
        if (rows != 1) {
            String message = "修改订单状态失败，服务器忙，请稍后再次尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_UPDATE, message);
        }
    }

    @Override
    public void setError(Long id) {
        log.debug("开始处理【根据id修该订单状态为异常】的业务,参数: {}",id);
        //创建Order对象
        Order order = new Order();
        LocalDateTime now = LocalDateTime.now();
        order.setId(id);
        order.setStatus(OrderStatusEnum.ERROR.getStatus());
        order.setModifiedData(now);
        //调用OrderMapper的updateById方法
        int rows = orderMapper.updateById(order);
        // 判断修改数据的结果是否符合预期
        if (rows != 1) {
            String message = "修改订单状态失败，服务器忙，请稍后再次尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_UPDATE, message);
        }
    }

    @Override
    public void restoreOrder(Long id) {
        log.debug("开始处理【还原订单】的业务,参数: {}",id);
        //创建Order对象
        Order order = new Order();
        LocalDateTime now = LocalDateTime.now();
        order.setId(id);
        order.setIsDelete(0);
        order.setModifiedData(now);
        //调用OrderMapper的updateById方法
        int rows = orderMapper.updateById(order);
        // 判断修改数据的结果是否符合预期
        if (rows != 1) {
            String message = "还原订单失败，服务器忙，请稍后再次尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_UPDATE, message);
        }
    }

    @Override
    public OrderListItemVO getOrderNew() {
        log.debug("开始处理【获取最新创建订单】的业务");
        OrderListItemVO orderNew = orderMapper.getOrderByTime(getUserId());
        return orderNew;
    }

    @Override
    public int countByWait() {
        log.debug("开始处理【统计等待接单的订单数】的业务");
        int rows = orderMapper.countByStatus(OrderStatusEnum.WAIT_DIST.getStatus());
        return rows;
    }

    @Override
    public int countByTransport() {
        log.debug("开始处理【统计派送中的订单数】的业务");
        int rows = orderMapper.countByStatus(OrderStatusEnum.TRANSPORT.getStatus());
        return rows;
    }

    @Override
    public int countByComplete() {
        log.debug("开始处理【统计已完成的订单数】的业务");
        int rows = orderMapper.countByStatus(OrderStatusEnum.COMPLETE.getStatus());
        return rows;
    }

    public LoginPrincipal getUserInfo(){
        // 编写获取SpringSecurity上下文的代码
        LoginPrincipal principal = (LoginPrincipal)
                SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        // 为了逻辑严谨,判断一下SpringSecurity上下文中信息是不是null
        if(principal == null){
            throw new ServiceException(
                    ServiceCode.ERR_UNAUTHORIZED,"您没有登录!");
        }
        return principal;
    }
    // 业务逻辑层需求中,实际上只需要用户的id
    // 我们可以再编写一个方法,从用户对象中获取id
    public Long getUserId(){
        return getUserInfo().getId();
    }
}
